<?php
namespace app\factory\logic;

use app\common\exception\LogicException;
use app\model\Factory;

/**
 * 猪厂签名类
 */
class FactorySignLogic
{
    /**
     * @Description 验证签名
     * @author: zj
     * @param string $key
     * @param string $timestamp
     * @param string $sign
     * @param string $body
     * @time 2024/03/11 14:23:34
     * @return array
     */
    public function checkSign(string $key, string $timestamp, string $sign, string $body)
    {
        $this->checkTimestamp($timestamp);

        $factoryInfo = $this->getFactoryInfo($key);

        $createSign = $this->createSign($key, $factoryInfo['secret'], $timestamp, $body);
        if ($createSign != $sign) {
            throw new LogicException('签名验证失败');
        }

        return [
            'factory_id' => $factoryInfo['id'],
            'key' => $factoryInfo['key'],
            'secret' => $factoryInfo['secret'],
        ];
    }

    /**
     * @Description 验证时间戳
     * @author: zj
     * @param string $timestamp
     * @time 2024/03/11 14:23:48
     * @return true
     */
    public function checkTimestamp(string $timestamp)
    {
        $now = time();
        if (abs(($now - (int)$timestamp)) > 60) {
            throw new LogicException('时间超出范围');
        }

        return true;
    }

    /**
     * @Description 创建签名
     * @author: zj
     * @param string $key
     * @param string $secret
     * @param string $timestamp
     * @param string $body
     * @time 2024/03/11 14:24:02
     * @return string
     */
    public function createSign(string $key, string $secret, string $timestamp, string $body)
    {
        $sign = $key. $timestamp. $secret. $body;

        return md5($sign);
    }

    /**
     * @Description 获取猪厂信息
     * @author: zj
     * @param string $key
     * @time 2024/03/11 14:24:20
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getFactoryInfo(string $key)
    {
        $info = cache()->get($key);
        if ($info) {
            return json_decode($info, true);
        }

        $factoryModel = new Factory();
        $info = $factoryModel->field('id,key,secret')
            ->where('key', $key)
            ->where('delete_time', $factoryModel)
            ->find();
        if (!$info) {
            throw new LogicException('猪厂不存在');
        }
        $info = $info->toArray();

        //写入缓存
        cache()->set($key, json_encode($info, JSON_UNESCAPED_UNICODE));

        return $info;
    }
}
